2つのAWS IoT CoreをMosquittoでブリッジ接続してデータを転送してみた
2024/8/5 設定ファイルの記述ミス(in→out)を修正
こんにちは。製造ビジネステクノロジー部のakkyです。
AWS IoT Coreではルールアクションを使うことでメッセージを様々なサービスに転送できますが、メッセージをそのまま別のIoT Coreへ転送するという機能はついていません。
開発中などに本番環境に流れているデータを実験用環境で利用したいというときに、大本の接続元を変えるというのは面倒なので、どうにかして本番用環境のIoT Coreから実験用環境のIoT Coreへメッセージを転送できないでしょうか?
いくつか手段を考えてみました
- IoT Core→SQS→Lambda→(HTTPS REST API経由)IoT Core
- IoT Core→(MQTTのまま転送)→IoT Core
1の方法では、SQSとLambdaのどこでアカウントを分けるか?という点を考える必要はあるものの、いずれにしてもクロスアカウントで運用は可能と思います。
今回は2の方法をとり、Mosquittoのブリッジ機能を使って、MQTTブローカー間でメッセージを転送してみましたのでご紹介します。
以下のAWS公式ブログを参考に、バージョンアップの対応と複数のIoT Coreへの拡張してみました。
Mosquitto
単体のMQTTブローカーとしてよく使われるEclipse Mosquittoには、メッセージを別のMQTTブローカーに転送するブリッジ機能が備わっています。
もちろんMosquitto自信もMQTTブローカーなので、Mosquitto→IoT Coreというシンプルな転送も可能ですが、IoT Core→Mosquitto→IoT Coreという複数のブローカーに接続する構成も可能となっています。
環境と構成
ブリッジとして使用するMosquittoは手元のPC(WSL2)で動かしました。
仮にEC2で動かす場合は、Amazon Linux 2023にはパッケージが用意されていないため、Ubuntuを使用する必要があります。
- OS Ubuntu 24.04 LTS
仮にEC2で動かすと構成としてはこのようになります。AWSアカウントを2つ使用しますが、EC2はどちらのアカウントで動かしても違いはないでしょう。
EC2はパブリックサブネットに配置してもよいですし、プライベートサブネット+NATゲートウェイまたはVPCエンドポイントでも接続できるはずです。
Mosquittoの設定
それぞれのIoT Coreでモノを作成し、クライアント証明書を取得しておきます。AmazonのCA証明書は共通です。
まずMosquittoをインストールします
sudo apt update
sudo apt install mosquitto
次に、クライアント証明書と秘密鍵を/etc/mosquitto/certs
にコピーします。また、CA証明書
(AmazonRootCA1.pem)を/etc/mosquitto/ca_certificates
にコピーします。(sudoが必要)
設定ファイルを/etc/mosquitto/conf.d/bridge.conf
に新規作成し、内容は次のようにしました。mosquitto.confのドキュメント
allow_anonymous false
listener 1883 127.0.0.1
connection awsiot1
address <送信元のエンドポイント>-ats.iot.ap-northeast-1.amazonaws.com:8883
bridge_protocol_version mqttv50
keepalive_interval 1200
notifications true
notifications_local_only true
# メッセージをsubscribeする
topic bridge/test1 in 1
bridge_insecure false
bridge_cafile /etc/mosquitto/ca_certificates/AmazonRootCA1.pem
bridge_certfile /etc/mosquitto/certs/<送信元のクライアント証明書>-certificate.pem.crt
bridge_keyfile /etc/mosquitto/certs/<送信元の秘密鍵>-private.pem.key
bridge_tls_version tlsv1.3
connection awsiot2
address <転送先のエンドポイント>-ats.iot.ap-northeast-1.amazonaws.com:8883
bridge_protocol_version mqttv50
keepalive_interval 1200
notifications true
notifications_local_only true
# メッセージをpublishする
topic bridge/test1 out 1
bridge_insecure false
bridge_cafile /etc/mosquitto/ca_certificates/AmazonRootCA1.pem
bridge_certfile /etc/mosquitto/certs/<転送先のクライアント証明書>-certificate.pem.crt
bridge_keyfile /etc/mosquitto/certs/<転送先の秘密鍵>-private.pem.key
bridge_tls_version tlsv1.3
この設定では、bridge/test1
というトピックにパブリッシュされたデータを転送します。つまり、送信元(構成図左)のIoT Coreに投稿されたメッセージが、転送先(構成図右)のIoT Coreへ転送されます。
転送するトピックに関する設定はもう少し細かく変更することができますので、ドキュメントのtopicの設定をご覧ください。
最後にMosquittoを再起動して完了です。
sudo systemctl restart mosquitto
これでメッセージが転送されるようになるはずです。
転送できていない場合には、私の場合には許可するTLSのバージョンが異なっていましたので、TLS1.3を許可するように変更してみてください。
動作確認
マネジメントコンソールのMQTTテストクライアントを使ってもいいのですが、片方のIoT Coreにしか接続できないので、もう片方に観察用のクライアントを使用するとわかりやすいと思います。
今回は送信元にMQTTXで接続し、受信側はMQTTテストクライアントを使い、メッセージが転送できることを確認できました。
以上